import web
import random
from player import Player

urls = ('/', 'index',
        '/game([0-9]*)-([0-9]*)', 'game',
        '/join', 'join',
        '/create', 'create',
        '/move', 'move',
        '/ajax/game_state/([0-9]*)', 'game_state',
        '/ajax/state/([0-9]*)/td([0-9]*)-([0-9]*)', 'state')
render = web.template.render('templates/', cache = False)

class index:
  def GET(self):
    games = web.select('games')
    web.output(render.index(games))
    
class create:
  def POST(self):
    i = web.input()
    n = web.insert('games', name = 'Game', alphabet = 1, amount = 2)
    # p = web.insert('players',
                   # word = i.word,
                   # game = n,
                   # comments = "",
                   # alphabet_state_1 = 0,
                   # alphabet_state_2 = 0)
    p = Player.create(n, i.word)
    # web.update('games', where = 'id = $n', turn = p, vars = locals())
    web.seeother('/game%d-%d' % (n, p.id()))

def count(guess, word):
  if guess == word:
    return '!'
  count = 0
  for a in guess:
    if word.find(a) != -1:
      count = count + 1
  return count
    
class game:
  def GET(self, game, player):
    g = web.select('games', where = 'id = $game', vars = locals())[0]
    alphabet = web.select('alphabet', where = 'id = $a', vars = {'a': g.alphabet})[0]
    # player_turn = g.turn
    # player_me = int(player)
    # mine_data_all = web.select('players',
                               # where = 'game = $game AND id = $player_me',
                               # vars = locals())
    # mine_data = mine_data_all[0]
    # word = mine_data['word']
    # assert len(word) == 4
    me = Player(player)
    player_me = me.id()
    word = me.word()
    guesses = web.select('guesses',
                         where = 'game = $game AND player = $player_me',
                         vars = locals())
    my_guesses = []
    for g in guesses:
      my_guesses.append(g.word)
    players = Player.participants(game)
    p_dict = []
    player_turn = -1 # it is possible that no one has a turn
    for p in players:
      if p.state() == Player.TURN:
        player_turn = p.id()
      if p.id() == player_me:
        continue
      his = web.select('guesses', where = 'game = $game AND player = $p',
                       vars = {'game': game, 'p': p.id()})
      p_dict.append({'id': p.id(),
                     'mine': [count(x, p.word()) for x in my_guesses],
                     'his' : [(h.word, count(h.word, word)) for h in his]})
    letters_1 = me.state_1()
    letters_2 = me.state_2()
    states = []
    alph_utf = alphabet.chars
    for i in range(len(alph_utf)):
      state = (letters_1 & 1) * 2 + (letters_2 & 1)
      letters_1 = letters_1 >> 1
      letters_2 = letters_2 >> 1
      states += [(alph_utf[i],state, i)]
    web.output(render.game(word,
                           game,
                           p_dict,
                           my_guesses,
                           player_me,
                           player_turn,
                           range(len(my_guesses)),
                           states))
    
class join:
  def POST(self):
    i = web.input()
    game_dict = {'g': i.game}
    already = web.select('players', what = 'COUNT(*) as amount', where = 'game = $g', vars = game_dict)[0]
    need = web.select('games', where = 'id = $g', vars = game_dict)[0]
    if (already.amount < need.amount):
      p = Player.create(i.game, i.word)
      if already.amount == need.amount - 1:
        web.update('players', where = 'game = $g', game_state = Player.WAIT_TURN, vars = game_dict)
        web.update('players', where = 'id = $p', game_state = Player.TURN, vars = {'p': p.id()})
      web.seeother('/game%d-%d' % (int(p.game()), p.id()))
    else:
      assert(False)
    
class game_state:
  def GET(self, player):
    player_id = int(player)
    g = web.select('players', where = 'id = $player_id', vars = locals())
    web.output(g[0].game_state)
    
class state:
  def GET(self, player, number, state):
    p = web.select('players', where = 'id = $player', vars = locals())[0]
    letters_1 = p['alphabet_state_1']
    letters_2 = p['alphabet_state_2']
    if (int(state) & 1) == 0:
      letters_2 &= (~(1 << int(number)))
    else:
      letters_2 |= (1 << int(number))
    if ((int(state)>>1) & 1) == 0:
      letters_1 &= (~(1 << int(number)))
    else:
      letters_1 |= (1 << int(number))
    web.update('players',
               where = 'id = $player',
               alphabet_state_1 = letters_1,
               alphabet_state_2 = letters_2,
               vars = locals())

class move:
  def POST(self):
    i = web.input()
    game_dict = dict(game_id = i.game)
    # we have to validate, that it is our turn
    game = web.select('games',
                      where = 'id = $game_id',
                      vars = game_dict)[0]
    game_dict['alphabet'] = game.alphabet
    game_dict['word'] = i.word
    guess = web.insert('guesses',
                       word = i.word,
                       game = i.game,
                       player = i.player)
    Player(i.player).set_wait_turn()
    web.seeother('/game%d-%d' % (int(i.game), int(i.player)))
    
web.webapi.internalerror = web.debugerror

if __name__ == '__main__':
  random.seed()
  import config
  web.run(urls, globals(), web.reloader)